package com.rytong.tools.ui.chart;

import java.util.ArrayList;
import java.util.List;

import com.rytong.tools.ui.Component;
import com.rytong.tools.ui.CssStyle;
import com.rytong.tools.ui.LPLayout;
import com.rytong.tools.ui.LPScrollView;
import com.rytong.tools.ui.LPLayout.MyLPLayout;
import com.rytong.tools.utils.Utils;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Shader;
import android.graphics.Paint.Style;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsoluteLayout;

/**
 * @author lixiao 方形立体柱状图
 */
@SuppressWarnings("deprecation")
public class LPCubePlotLayout extends Component implements Chart {

    // x轴的marginTop
    float xScaleMaginTop_;
    // y轴的marginTop
    float yScaleMaginTop_;
    // y轴的刻度值集合
    List<String> yValueSpace_;
    //x轴的刻度值集合
    List<String> xValueSpace_;
    //每个刻度值上放几个柱子
    int num_;
    
    // 柱子视图
    public class LPCubePlotView extends View {

        Component component_;
        // 样式
        CssStyle cssStyle_;
        // 画笔
        Paint paint_;
        // 点击事件
        String onClickValue_;
        // 渐变色属性
        int gradientType_;
        int startColorStr_;
        int endColorStr_;
        // 柱子的宽高
        int barWidth_;
        int barHeight_;
        // 渐变属性
        LinearGradient mLinearGradient_;
        // 记录是第几根柱子(从0开始)
        int number_;

        public LPCubePlotView(Context context) {
            super(context);
        }

        public LPCubePlotView(Context context, Component c, int number) {
            super(context);
            component_ = c;
            number_ = number;
        }

        public void mould() throws Exception {
            // 设置画笔
            paint_ = new Paint();
            paint_.setAntiAlias(true);
            paint_.setStyle(Style.FILL);
            // 获得点击时的lua事件
            onClickValue_ = (String) component_.property_.get("onclick");
            cssStyle_ = component_.cssStyle();
            // 获得颜色渐变相关属性
            if (cssStyle_ != null) {
                gradientType_ = cssStyle_.gradientType;
                startColorStr_ = cssStyle_.startColorStr;
                endColorStr_ = cssStyle_.endColorStr;
            }
            // 获取柱子的value
            String compontValue = (String) component_.getPropertyByName("value");

            android.widget.AbsoluteLayout.LayoutParams lp = null;
//            if (component_.left_ > 0) {
//                // 获得柱子正面的宽高
//                barWidth_ = component_.width_;
//                barHeight_ = component_.height_;
//                //如果服务端没给height，则根据value计算
//                if(barHeight_ <= 0){
//                    if (yValueSpace_ == null)
//                        return;
//                    int valueSize = yValueSpace_.size();
//                    barHeight_ = (int) ((valueSize - 1) * yScaleMaginTop_ * Float.parseFloat(compontValue) / (Float
//                            .parseFloat(yValueSpace_.get(0)) - Float.parseFloat(yValueSpace_.get(valueSize - 1))));
//                }
//                //计算柱子的top值
//                if(component_.top_ <= 0 ){
//                    component_.top_ = barHeight_;
//                }
//                lp = new android.widget.AbsoluteLayout.LayoutParams(component_.width_ * 5 / 4,
//                        (int) (component_.height_ + component_.width_ * Math.sqrt(3) / 4), component_.left_,
//                        (int) (LPCubePlotLayout.this.height_ - component_.top_ - component_.width_ * Math.sqrt(3) / 4));
//            } else {
                if (yValueSpace_ == null)
                    return;
                int valueSize = yValueSpace_.size();
                // 获得柱子正面的宽高
                barWidth_ = component_.width_;
                if(!compontValue.equals("")){
                	barHeight_ = (int) ((valueSize - 1) * yScaleMaginTop_ * Float.parseFloat(compontValue) / (Float
                	    .parseFloat(yValueSpace_.get(0)) - Float.parseFloat(yValueSpace_.get(valueSize - 1))));
                }
                //当前柱子落在第几个刻度值上(从0开始)
                int currentXValueNum = (number_) / num_;
                //此柱子在刻度上排第几位(当一个刻度上有多个柱子时,从0开始)
                int currentPlaceNum = (number_) % num_;
                //柱子之间间距
                float space = 8.0f;
                int currentX = 0;
                int currentY = 0;
                
                //计算layoutParams的x、y
                if(num_ % 2 == 0){//刻度点上柱子的个数为偶数时
                    currentX =  (int) (xScaleMaginTop_ * (currentXValueNum + 0.5) - (num_ / 2) * barWidth_ - space * ((num_ / 2) - 1 + 0.5) + currentPlaceNum * (barWidth_ + space));
                }else {//刻度点上柱子的个数为基数时
                    currentX =  (int) (xScaleMaginTop_ * (currentXValueNum + 0.5) - ((num_ / 2) + 0.5) * barWidth_ - space * (num_ / 2) + currentPlaceNum * (barWidth_ + space));
                }
                currentY =  (int) (LPCubePlotLayout.this.height_ - barHeight_ - barWidth_ * Math.sqrt(3) / 4);
                
                
                
                lp = new android.widget.AbsoluteLayout.LayoutParams(barWidth_ * 5 / 4, (int) (barHeight_ + barWidth_
                        * Math.sqrt(3) / 4), currentX, currentY);
                component_.left_ = currentX;
                component_.top_ =  currentY;
//            }
            this.setLayoutParams(lp);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);

            //没有设置value值的柱子不显示
            if(component_.getPropertyByName("value").equals("")){
                return;
            }
            // 绘制上面(角度为60度，侧边长为柱子宽度的一半)
            Path path1 = new Path();
            path1.moveTo(0, (float) (barWidth_ * Math.sqrt(3) / 4.0f));
            path1.lineTo(barWidth_, (float) (barWidth_ * Math.sqrt(3) / 4.0f));
            path1.lineTo(barWidth_ * 5 / 4.0f, 0);
            path1.lineTo(barWidth_ / 4.0f, 0);
            path1.close();
            paint_.setColor(setColorBright(startColorStr_, 1.2f));
            canvas.drawPath(path1, paint_);

            // 绘制正面
            Path path2 = new Path();
            if (gradientType_ == 1) {// 水平渐变
                mLinearGradient_ = new LinearGradient(0, (float) (barWidth_ * Math.sqrt(3) / 4.0f), barWidth_,
                        (float) (barWidth_ * Math.sqrt(3) / 4.0f), new int[] { startColorStr_, endColorStr_ }, null,
                        Shader.TileMode.MIRROR);
            } else {// 垂直渐变
                mLinearGradient_ = new LinearGradient(0, (float) (barWidth_ * Math.sqrt(3) / 4.0f), 0,
                        (float) (barHeight_ + barWidth_ * Math.sqrt(3) / 4.0f),
                        new int[] { startColorStr_, endColorStr_ }, null, Shader.TileMode.MIRROR);
            }
            path2.moveTo(0, (float) (barWidth_ * Math.sqrt(3) / 4.0f));
            path2.lineTo(barWidth_, (float) (barWidth_ * Math.sqrt(3) / 4.0f));
            path2.lineTo(barWidth_, (float) (barHeight_ + barWidth_ * Math.sqrt(3) / 4.0f));
            path2.lineTo(0, (float) (barHeight_ + barWidth_ * Math.sqrt(3) / 4.0f));
            path2.close();
            paint_.setShader(mLinearGradient_);
            canvas.drawPath(path2, paint_);

            // 绘制侧面
            Path path3 = new Path();
            path3.moveTo(barWidth_, (float) (barWidth_ * Math.sqrt(3) / 4.0f));
            path3.lineTo(barWidth_, (float) (barHeight_ + barWidth_ * Math.sqrt(3) / 4.0f));
            path3.lineTo(barWidth_ * 5 / 4.0f, barHeight_);
            path3.lineTo(barWidth_ * 5 / 4.0f, 0);
            paint_.setShader(null);
            paint_.setColor(setColorBright(endColorStr_, 0.8f));
            canvas.drawPath(path3, paint_);
        }
        
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            super.onTouchEvent(event);
            int touchEvent = event.getAction();
            switch (touchEvent) {
            case MotionEvent.ACTION_DOWN:
            	// 按下tr时候变色。
            	trDownColor(tr_, llvSV_);
                xDown_ = event.getX();
                yDown_ = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
            	// 移动tr恢复颜色。
            	int offset = (int) Math.abs(yDown_ - event.getY());
            	if (offset > offset_) {
            		trMoveColor(tr_, llvSV_);
            	}
                moveY(yDown_, event.getY());
                break;
            case MotionEvent.ACTION_UP:
            	// 抬起tr恢复颜色。
            	trUpColor(tr_, llvSV_);
                onClick(onClickValue_);
                break;
            default:

            }
            return true;
        }

    }

    public class MyLPCubePlotLayout extends AbsoluteLayout implements CompositedComponent {

        public MyLPCubePlotLayout(Context context, String value) {
            super(context);
        }

        @Override
        public Component composited() {
            return LPCubePlotLayout.this;
        }
        
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            	// 按下tr时候变色。
            	trDownColor(tr_, llvSV_);
                xDown_ = event.getX();
                yDown_ = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
            	// 移动tr恢复颜色。
            	int offset = (int) Math.abs(yDown_ - event.getY());
            	if (offset > offset_) {
            		trMoveColor(tr_, llvSV_);
            	}
                moveY(yDown_, event.getY());
                break;
            }
            return super.onTouchEvent(event);
        }

    }

    @Override
    public void initRealView(Activity activity, String nodeValue) {
        super.initRealView(activity, nodeValue);
        realView_ = new MyLPCubePlotLayout(activity, nodeValue);
        childrenList_ = new ArrayList<Component>();
    }

    @Override
    public void mouldW() throws Exception {
        mouldChildList();
        ((ViewGroup) realView_).removeAllViews();
        int size = childrenList_.size();
        Component child = null;
        if(xValueSpace_ == null)
            return;
        int xValueSize = xValueSpace_.size(); 
        if(size % xValueSize == 0){
            num_ = size / xValueSize;
        }else {
            num_ = (size / xValueSize) + 1;
        }
        for (int i = 0; i < size; i++) {
            child = (Component) childrenList_.get(i);
            LPCubePlotView lpCubePlotView = new LPCubePlotView(getContext(), child, i);
            lpCubePlotView.mould();
            ((ViewGroup) realView_).addView(lpCubePlotView);
        }
    }
    
    private int setColorBright(int color, float scale){
        float[] hsv = new float[3];
        Color.RGBToHSV(Color.red(color), Color.green(color), Color.blue(color), hsv);
        float[] hsvBright = new float[3];
        for (int i = 0; i < hsv.length; i++) {
            if(i == hsv.length - 1){
                hsvBright[i] = hsv[i] * scale;
            }else {
                hsvBright[i] = hsv[i];
            }
        }
        color = Color.HSVToColor(hsvBright);
        return color;
    }

    @Override
    public void setXScaleMarginTop(float valueSpace) {
        xScaleMaginTop_ = valueSpace;
    }

    @Override
    public float getXScalemarginTop() {
        return xScaleMaginTop_;
    }

    @Override
    public void setYScaleMarginTop(float valueSpace) {
        yScaleMaginTop_ = valueSpace;
    }

    @Override
    public float getYScaleMarginTop() {
        return yScaleMaginTop_;
    }

    @Override
    public void setYScaleValues(List<String> values) {
        yValueSpace_ = values;
    }

    @Override
    public List<String> getYScaleVaues() {
        return yValueSpace_;
    }

    @Override
    public void setXScaleValues(List<String> values) {
        xValueSpace_ = values;
    }

    @Override
    public List<String> getXScaleValue() {
        return xValueSpace_;
    }

    @Override
    public void releaseResource(Component component) {
    	super.releaseResource(component);
    	if(xValueSpace_ != null){
    		xValueSpace_.clear();
    		xValueSpace_ = null;
    	}
    	if(yValueSpace_ != null){
    		yValueSpace_.clear();
    		yValueSpace_ = null;
    	}
    }
}
